<template>
	<view class="chat-detail">
		<view class="msg-content" ref="msgContent" :style="{height: scrollHeight - keyboardHeight + 'px'}">
			<scroll-view :style="{height: scrollHeight - keyboardHeight + 'px'}" class="scroll-view" :scroll-top="scrollTop" scroll-y
				:refresher-enabled="refresherEnabled" :refresher-threshold="50" :show-scrollbar="false"
				refresher-background="#f6f6f6" :refresher-triggered="triggered"
				@refresherrefresh="onRefresh" @touchmove.stop
				:scroll-into-view="scrollIntoView" :enhanced="true" :bounces="false" @scrolltolower="scrolltolower" >
				<view class="list">
					<view class="item" v-for="(item, index) in list" :key="index" :id="'id_'+ item.id">
						{{item.content}}
					</view>
				</view>
			</scroll-view>
		</view>

		<view class="footer">
			<image src="/static/chat/voice.svg" mode=""></image>
			<view class="inp">
				<input ref="inp" type="text" placeholder="" @focus="onfocus" @blur="onblur" v-model="msg" confirm-type="send" @keyboardheightchange="keyboardheightchange" @confirm="sendMsg" />
			</view>
			<image src="/static/chat/smile.svg" mode=""></image>
			<image src="/static/chat/more.svg" mode=""></image>
		</view>
		<view class="block" v-if="!isFocus"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				scrollTop: 0, 
				scrollHeight: 0, // 消息内容高度
				keyboardHeight: 0, // 键盘高度
				isFocus: false, // 是否聚焦,用来控制安全区域的白块显隐
				scrollIntoView: null, // 用来滚动到指定的消息位置
				_scrollIntoView: null, // 加载更多后,定位到这个记录点位置
				scrollWithAnimation: true, // 在设置滚动条位置时使用动画过渡
				refresherEnabled: true, // 是否开启下拉刷新
				list: [], // 消息列表
				triggered: false, // 设置当前下拉刷新状态，true 表示下拉刷新已经被触发，false 表示下拉刷新未被触发
				_freshing: false, // 是否正在刷新
				msg: '', // 要发送的消息内容
			};
		},
		async created() {
			await this.getMainHeight()
			await this.getList()
			await this.scroll2Bottom()
		},
		methods: {
			// 获取内容高度
			async getMainHeight () {
				this.$nextTick(async ()=>{
					const data = await this.queryDom('.msg-content')
					console.log(data)
					this.scrollHeight = data[0].height
				})
			},
			// 获取消息列表数据
			async getList() {
				uni.showLoading({
					title: '加载中'
				})
				let max = this.list.length + 20
				for (let i = this.list.length; i < max; i++) {
					this.list.unshift({content: i, id: i})
				}
				uni.hideLoading()
				if(this._scrollIntoView) {
					this.$nextTick(()=>{
						setTimeout(async ()=>{
							this.scrollIntoView = this._scrollIntoView
							const data = await this.queryDom('.item')
							if(data.length) {
								this._scrollIntoView = data[0].id
							}
						}, 0)
					})
					
				}
			},
			/** 消息发送 **/
			async sendMsg () {
				if(!this.msg) return uni.showToast({title: '发送内容为空', icon: 'none'})
				this.list.push({content: this.msg, id: this.list.length})
				await this.scroll2Bottom()
				this.msg = ''
			},
			/** 加载更多操作 **/
			onPulling() {
				console.log('onPulling')
				this.getList()
			},
			async onRefresh() {
				if (!this.refresherEnabled) return
				if (this._freshing) return;
				this._freshing = true;
				this.triggered = true
				try {
					await this.getList()
				} catch (e) {
					console.log(e)
				} finally {
					this.triggered = false;
					this._freshing = false;
				}
			},
			async scroll2Bottom() {
				let This = this
				This.$nextTick(async ()=>{
					const data = await this.queryDom('.item')
					console.log(data)
					if(data.length) {
						This.scrollIntoView = data[data.length - 1].id
						This._scrollIntoView = data[0].id
					}
				})
			},
			scrolltolower () {
				console.log('scrolltolower')
			},
			async onfocus() {
				this.isFocus = true
				this.$refs.inp.focus();
				await this.getMainHeight()
			},
			async onblur() {
				this.isFocus = false
				this.keyboardHeight = 0
				await this.getMainHeight()
			},
			/** 键盘弹起,重新计算内容高度 **/
			async keyboardchange({detail}) {
				this.keyboardHeight = detail.height
				const data = await this.queryDom('.scrollbox')
				this.scrollTop = data[0].height
				await this.getMainHeight()
			},
			async queryDom(dom) {
				let This = this
				if (!dom) return
				return new Promise((resolve, reject) => {
					This.$nextTick(() => {
						let query = uni.createSelectorQuery().in(This);
						query.selectAll(dom).boundingClientRect((data) => {
							resolve(data)
						}).exec()
					})
				})
			},
		}
	}
</script>

<style lang="scss" scoped>
	.chat-detail {
		width: 100vw;
		height: 100vh;
		display: flex;
		flex-direction: column;
		background-color: #f6f6f6;

		.msg-content {
			flex: 1;

			.scroll-view {
				.list {
					padding: 32rpx;

					.item {
						background-color: #fff;
						border-radius: 10rpx;
						padding: 10rpx;
						margin-bottom: 20rpx;
						&:last-child {
							margin-bottom: 0;
						}
					}
				}
			}
		}


		.footer {
			box-sizing: border-box;
			padding-left: 20rpx;
			padding-right: 20rpx;
			height: 100rpx;
			background: #fff;
			display: flex;
			align-items: center;
			box-shadow: 0 0 16rpx 0 rgba(232,237,250,.6),0 4rpx 8rpx 0 rgba(232,237,250,.5);
			.inp {
				flex: 1;
				height: 80rpx;
				background-color: #f6f6f6;
				margin: 0 12rpx;
				border-radius: 10rpx;
				padding: 0 10rpx;

				input {
					height: 80rpx;
				}
			}

			image {
				width: 50rpx;
				height: 50rpx;
				flex: none;
				margin: 0 12rpx;
			}
		}

		.block {
			height: env(safe-area-inset-bottom);
			background-color: #fff;
		}
	}
</style>